//****************************************************************************
//                      RGB_maping
//
//功能：TCON RGB 灰度变换
//
//版本:
//****************************************************************************
module RGB_maping(
		input	wire			resetb	,
		input	wire			sclk,
		
		input	wire			test_mode,
		input	wire			work_mode,
		
		input	wire			cfg_wen,
		input	wire	[11:0]	cfg_waddr,
		input	wire	[7:0]	cfg_wdata,
		
		input	wire			pclk,
		input	wire			vsin,
		input	wire			hsin,
		input	wire			dein,
		input	wire	[47:0]	din,
		
		output	reg				vsout,
		output	reg				hsout,
		output	reg				deout,
		output	reg		[47:0]	dout
		);

//******************************************************************************
//                              参数定义
//******************************************************************************

//******************************************************************************
//                              信号定义
//******************************************************************************
reg				Map_Off_sclk, Map_Off;

reg				r_wen, g_wen, b_wen;
wire	[8:0]	waddr;
wire	[7:0]	wdata;

(*keep*)wire	[7:0]	rin_odd, gin_odd, bin_odd, rin_even, gin_even, bin_even;
(*keep*)wire	[15:0]	r_odd_a, g_odd_a, b_odd_a, r_even_a, g_even_a, b_even_a;
(*keep*)reg		[9:0]	r_odd_b, g_odd_b, b_odd_b, r_even_b, g_even_b, b_even_b;
(*keep*)reg		[7:0]	r_odd_c, g_odd_c, b_odd_c, r_even_c, g_even_c, b_even_c;

reg		[2:0]	vs_t, hs_t, de_t;
reg				vs_b, hs_b, de_b;

reg		[1:0]	i_f_count, i_h_count, l_odd_num, l_even_num;

//******************************************************************************
//                              映射表
//******************************************************************************
assign	rin_odd		= din[7:0];
assign	gin_odd		= din[15:8];
assign	bin_odd		= din[23:16];
assign	rin_even	= din[31:24];
assign	gin_even	= din[39:32];
assign	bin_even	= din[47:40];

// RGM映射
gray_map_table #(.INIT_FILE("../design/MIF/R_map_1.mif"))
	r0_map(
		.clka	( sclk ),
		.cea	( r_wen ),
		.addra	( waddr ),
		.dia	( wdata ),
		
		.clkb	( pclk ),
		.rstb	( 1'b0 ),
		.addrb	( rin_odd ),
		.dob	( r_odd_a )
		);
		
gray_map_table #(.INIT_FILE("../design/MIF/G_map_1.mif"))
	g0_map(
		.clka	( sclk ),
		.cea	( g_wen ),
		.addra	( waddr ),
		.dia	( wdata ),
		
		.clkb	( pclk ),
		.rstb	( 1'b0 ),
		.addrb	( gin_odd ),
		.dob	( g_odd_a )
		);
		
gray_map_table #(.INIT_FILE("../design/MIF/B_map_1.mif"))
	b0_map(
		.clka	( sclk ),
		.cea	( b_wen ),
		.addra	( waddr ),
		.dia	( wdata ),
		
		.clkb	( pclk ),
		.rstb	( 1'b0 ),
		.addrb	( bin_odd ),
		.dob	( b_odd_a )
		);
		
gray_map_table #(.INIT_FILE("../design/MIF/R_map_1.mif"))
	r1_map(
		.clka	( sclk ),
		.cea	( r_wen ),
		.addra	( waddr ),
		.dia	( wdata ),
		
		.clkb	( pclk ),
		.rstb	( 1'b0 ),
		.addrb	( rin_even ),
		.dob	( r_even_a )
		);
		
gray_map_table #(.INIT_FILE("../design/MIF/G_map_1.mif"))
	g1_map(
		.clka	( sclk ),
		.cea	( g_wen ),
		.addra	( waddr ),
		.dia	( wdata ),
		
		.clkb	( pclk ),
		.rstb	( 1'b0 ),
		.addrb	( gin_even ),
		.dob	( g_even_a )
		);
		
gray_map_table #(.INIT_FILE("../design/MIF/B_map_1.mif"))
	b1_map(
		.clka	( sclk ),
		.cea	( b_wen ),
		.addra	( waddr ),
		.dia	( wdata ),
		
		.clkb	( pclk ),
		.rstb	( 1'b0 ),
		.addrb	( bin_even ),
		.dob	( b_even_a )
		);
		
//******************************************************************************
//                              参数设置
//******************************************************************************
always	@(posedge sclk or negedge resetb)
	if (resetb == 0)
		Map_Off_sclk <= 0;
	else if (cfg_wen == 1)
		case (cfg_waddr)
			12'h111:	Map_Off_sclk <= cfg_wdata;
		endcase
		
assign	waddr = cfg_waddr[8:0];
assign	wdata = cfg_wdata;
		
always	@(posedge sclk)
	if (cfg_waddr[11:9] == 3'b100)
		r_wen <= cfg_wen;
	else
		r_wen <= 0;
		
always	@(posedge sclk)
	if (cfg_waddr[11:9] == 3'b101)
		g_wen <= cfg_wen;
	else
		g_wen <= 0;
		
always	@(posedge sclk)
	if (cfg_waddr[11:9] == 3'b110)
		b_wen <= cfg_wen;
	else
		b_wen <= 0;
		
//******************************************************************************
//                              映射输出
//******************************************************************************
always	@(posedge pclk)
	Map_Off <= Map_Off_sclk;

always	@(posedge pclk) begin
	vs_t <= {vs_t[1:0], vsin};
	hs_t <= {hs_t[1:0], hsin};
	de_t <= {de_t[1:0], dein};
	end

always	@(posedge pclk)
	if (work_mode == 0) begin
		vs_b <= 0;
		hs_b <= 0;
		de_b <= 0;
		end
	else if ((Map_Off == 1) || (test_mode == 1))begin
		vs_b <= vsin;
		hs_b <= hsin;
		de_b <= dein;
		end
	else begin
		vs_b <= vs_t[1];
		hs_b <= hs_t[1];
		de_b <= de_t[1];
	end
		
always	@(posedge pclk)
	if ((Map_Off == 1) || (test_mode == 1)) begin
		r_odd_b		<= {rin_odd, 2'b00};
		g_odd_b		<= {gin_odd, 2'b00};
		b_odd_b		<= {bin_odd, 2'b00};
		r_even_b	<= {rin_even, 2'b00};
		g_even_b	<= {gin_even, 2'b00};
		b_even_b	<= {bin_even, 2'b00};
		end
	else if (de_t[1] == 0) begin
		r_odd_b		<= 0;
		g_odd_b		<= 0;
		b_odd_b		<= 0;
		r_even_b	<= 0;
		g_even_b	<= 0;
		b_even_b	<= 0;
		end
	else begin
		r_odd_b		<= r_odd_a[9:0];
		g_odd_b		<= g_odd_a[9:0];
		b_odd_b		<= b_odd_a[9:0];
		r_even_b	<= r_even_a[9:0];
		g_even_b	<= g_even_a[9:0];
		b_even_b	<= b_even_a[9:0];
		end
		
//******************************************************************************
//                              8bit->10bit
//******************************************************************************
//帧计数
always @(posedge pclk or negedge resetb)
	if (resetb == 0)
		i_f_count <= 0;
	else if (vs_t[2:1] == 2'b01)
		i_f_count <= i_f_count + 1;	

//行计数
always @(posedge pclk)
	if (vs_t[2] == 1)
		i_h_count <= 0;	
	else if (de_t[2:1] == 2'b01)
		i_h_count <= i_h_count + 1;	

//odd位置码
always @(posedge pclk)
	l_odd_num <= i_f_count + {i_h_count[0], 1'b0};

//even位置码
always @(posedge pclk)
	l_even_num <= i_f_count + {~i_h_count[0], 1'b1};

//r_odd
always @(posedge pclk)
	if ((de_b == 0) || (work_mode == 0))
		r_odd_c <= 0;
	else if (r_odd_b[9:2] == 8'hFF)
		r_odd_c <= r_odd_b[9:2];
	else if (r_odd_b[1:0] <= l_odd_num)
		r_odd_c <= r_odd_b[9:2];
	else 
		r_odd_c <= r_odd_b[9:2] + 1;

//g_odd
always @(posedge pclk)
	if ((de_b == 0) || (work_mode == 0))
		g_odd_c <= 0;
	else if (g_odd_b[9:2] == 8'hFF)
		g_odd_c <= g_odd_b[9:2];
	else if (g_odd_b[1:0] <= l_odd_num)
		g_odd_c <= g_odd_b[9:2];
	else 
		g_odd_c <= g_odd_b[9:2] + 1;

//b_odd
always @(posedge pclk)
	if ((de_b == 0) || (work_mode == 0))
		b_odd_c <= 0;
	else if (b_odd_b[9:2] == 8'hFF)
		b_odd_c <= b_odd_b[9:2];
	else if (b_odd_b[1:0] <= l_odd_num)
		b_odd_c <= b_odd_b[9:2];
	else 
		b_odd_c <= b_odd_b[9:2] + 1;

//r_even
always @(posedge pclk)
	if ((de_b == 0) || (work_mode == 0))
		r_even_c <= 0;
	else if (r_even_b[9:2] == 8'hFF)
		r_even_c <= r_even_b[9:2];
	else if (r_even_b[1:0] <= l_even_num)
		r_even_c <= r_even_b[9:2];
	else 
		r_even_c <= r_even_b[9:2] + 1;

//g_even
always @(posedge pclk)
	if ((de_b == 0) || (work_mode == 0))
		g_even_c <= 0;
	else if (g_even_b[9:2] == 8'hFF)
		g_even_c <= g_even_b[9:2];
	else if (g_even_b[1:0] <= l_even_num)
		g_even_c <= g_even_b[9:2];
	else 
		g_even_c <= g_even_b[9:2] + 1;

//b_even
always @(posedge pclk)
	if ((de_b == 0) || (work_mode == 0))
		b_even_c <= 0;
	else if (b_even_b[9:2] == 8'hFF)
		b_even_c <= b_even_b[9:2];
	else if (b_even_b[1:0] <= l_even_num)
		b_even_c <= b_even_b[9:2];
	else 
		b_even_c <= b_even_b[9:2] + 1;

always	@(posedge pclk) begin
		vsout <= vs_b;
		hsout <= hs_b;
		deout <= de_b;
		end

always	@( * )
	dout <= {b_even_c, g_even_c, r_even_c, b_odd_c, g_odd_c, r_odd_c};
 
endmodule